package com.addplus.townmall.server.web.provider.serviceimpl.paperModule;

import com.addplus.townmall.server.api.constant.ErrorCode;
import com.addplus.townmall.server.api.exception.ErrorException;
import com.addplus.townmall.server.api.mapper.exam.PaperMapper;
import com.addplus.townmall.server.api.mapper.exam.PaperQuestionMapper;
import com.addplus.townmall.server.api.mapper.exam.QuestionMapper;
import com.addplus.townmall.server.api.model.exam.*;
import com.addplus.townmall.server.api.service.web.paperModule.PaperService;
import com.addplus.townmall.server.api.utils.DataUtils;
import com.addplus.townmall.server.web.provider.serviceimpl.questionModule.QuestionServiceImpl;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.RpcContext;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

@Service(interfaceClass = PaperService.class)
public class PaperServiceImpl implements PaperService {
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private PaperQuestionMapper paperQuestionMapper;

    @Override
    public List<AutoPaperQuestionNum> getQuestionByKnowledge(String knowledgeListValue) throws Exception {
        if(DataUtils.isEmpty(knowledgeListValue)){
            return null;
        }
        String[] knowledgeArr=knowledgeListValue.split(",");
        for(String str:knowledgeArr){
            AutoPaperQuestionNum autoPaperQuestionNum=new AutoPaperQuestionNum();

        }
        return null;
    }

    @Override
    public IPage<PaperExtend> getAllPaperByPage(Integer papeNum, Integer papeSize) throws Exception {
        if(DataUtils.EmptyOrNegativeOrZero(papeNum,papeSize)){
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        IPage<PaperExtend> iPage=new Page<>(papeNum,papeSize);
        List<PaperExtend> paperExtendList=paperMapper.getAllPaperByPage(iPage);
        BeanUtils.copyProperties(iPage.getRecords(),paperExtendList);
        for (PaperExtend paperExtend:paperExtendList){
            QueryWrapper<PaperQuestion> questionQueryWrapper=new QueryWrapper<>();
            questionQueryWrapper.eq("is_deleted",0);
            questionQueryWrapper.eq("paper_id",paperExtend.getId());
            List<PaperQuestion> paperQuestions=paperQuestionMapper.selectList(questionQueryWrapper);
            paperExtend.setPaperQuestionList(paperQuestions);
        }
        iPage.setRecords(paperExtendList);
        return iPage;
    }

    @Override
    public QuestionNumData getQuestionNumber() throws Exception {
        QuestionNumData questionNumData=new QuestionNumData();
        QueryWrapper<Question> questionQueryWrapper=new QueryWrapper<>();
        questionQueryWrapper.eq("question_type","单选题");
        questionQueryWrapper.eq("is_deleted",0);
        questionNumData.setDan(questionMapper.selectCount(questionQueryWrapper));

        questionQueryWrapper=new QueryWrapper<>();
        questionQueryWrapper.eq("question_type","多选题");
        questionQueryWrapper.eq("is_deleted",0);
        questionNumData.setDuo(questionMapper.selectCount(questionQueryWrapper));

        questionQueryWrapper=new QueryWrapper<>();
        questionQueryWrapper.eq("question_type","判断题");
        questionQueryWrapper.eq("is_deleted",0);
        questionNumData.setPan(questionMapper.selectCount(questionQueryWrapper));

        questionQueryWrapper=new QueryWrapper<>();
        questionQueryWrapper.eq("question_type","填空题");
        questionQueryWrapper.eq("is_deleted",0);
        questionNumData.setTian(questionMapper.selectCount(questionQueryWrapper));

        questionQueryWrapper=new QueryWrapper<>();
        questionQueryWrapper.eq("question_type","解答题");
        questionQueryWrapper.eq("is_deleted",0);
        questionNumData.setJie(questionMapper.selectCount(questionQueryWrapper));

        questionQueryWrapper=new QueryWrapper<>();
        questionQueryWrapper.eq("question_type","编程题");
        questionQueryWrapper.eq("is_deleted",0);
        questionNumData.setQi(questionMapper.selectCount(questionQueryWrapper));
        return questionNumData;
    }
    private static int index;
    private static int questionIndex;
    @Override
    public Map<String,Object> exportPaper(PaperExtend paperExtend) throws Exception {
        if(DataUtils.isEmptyObject(paperExtend)||DataUtils.isEmpty(paperExtend.getPaperName())){
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Date date=new Date();
        paperExtend.setIsDeleted(0);
        paperExtend.setGmtCreate(date);
        paperExtend.setGmtModified(date);
        paperExtend.setModifyUser(Integer.valueOf(RpcContext.getContext().getAttachment("id")));
        paperMapper.insert(paperExtend);
        PaperQuestion paperQuestion=null;

        Map<String,Object> dataMap=new HashMap<>();
        dataMap.put("paperName",paperExtend.getPaperName());
        dataMap.put("answerTitle",paperExtend.getPaperName()+"答案及评分标准");
        index=1;
        questionIndex=1;
        List<Map<String,Object>> allQuestionList=new ArrayList<>();
        if(paperExtend.getDanNum()>0){
            allQuestionList.add(getQuestionList(paperExtend.getId(),paperExtend.getDanNum(),paperExtend.getDanScore(),"单选题",date));
        }
        if(paperExtend.getDuoNum()>0){
            allQuestionList.add(getQuestionList(paperExtend.getId(),paperExtend.getDuoNum(),paperExtend.getDuoScore(),"多选题",date));
        }
        if(paperExtend.getPanNum()>0){
            allQuestionList.add(getQuestionList(paperExtend.getId(),paperExtend.getPanNum(),paperExtend.getPanScore(),"判断题",date));
        }
        if(paperExtend.getTianNum()>0){
            allQuestionList.add(getQuestionList(paperExtend.getId(),paperExtend.getTianNum(),paperExtend.getTianScore(),"填空题",date));
        }
        if(paperExtend.getJieNum()>0){
            allQuestionList.add(getQuestionList(paperExtend.getId(),paperExtend.getJieNum(),paperExtend.getJieScore(),"解答题",date));
        }
        if(paperExtend.getQiNum()>0){
            allQuestionList.add(getQuestionList(paperExtend.getId(),paperExtend.getQiNum(),paperExtend.getQiScore(),"其他",date));
        }
        dataMap.put("allQuestionList",allQuestionList);

        return dataMap;
    }

    @Override
    public Map<String, Object> autoExportPaper(ExportFormValue exportFormValue) throws Exception {
        if(DataUtils.isEmptyObject(exportFormValue,exportFormValue.getAutoPaperQuestionNumList())||DataUtils.EmptyOrNegativeOrZero(exportFormValue.getAutoPaperQuestionNumList().size())||DataUtils.isEmpty(exportFormValue.getPaperName())){
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }

        Paper paper=new Paper();
        Date date=new Date();
        paper.setIsDeleted(0);
        paper.setGmtCreate(date);
        paper.setGmtModified(date);
        paper.setModifyUser(Integer.valueOf(RpcContext.getContext().getAttachment("id")));
        paper.setPaperName(exportFormValue.getPaperName());
        String describe=exportFormValue.getPaperDescribe();
        if(describe!=null&&!describe.equals("")&&!describe.equals("undefined")){
            paper.setPaperDescribe(describe);
        }
        paperMapper.insert(paper);
        Map<String,Object> dataMap=new HashMap<>();
        String[] questionTypeArr={"单选题","多选题","判断题","填空题","解答题","编程题"};
        int[] typeScoreArr={0,0,0,0,0,0};
        List<AutoPaperQuestionNum> autoPaperQuestionNumList=exportFormValue.getAutoPaperQuestionNumList();
        List<Question> questionList=new ArrayList<>();
        for(AutoPaperQuestionNum autoPaperQuestionNum:autoPaperQuestionNumList){
            if(autoPaperQuestionNum.getQuestionChoiceNum()>0){
                List<QuestionTypeNum> questionTypeNumList=autoPaperQuestionNum.getQuestionTypeNumList();
                boolean isChoiceByType=false;
                if(questionTypeNumList!=null&&autoPaperQuestionNum.getQuestionTypeNumList().size()>0){
                    for(QuestionTypeNum questionTypeNum:questionTypeNumList){
                        if(questionTypeNum.getTypeQuestionChoiceNum()!=null&&questionTypeNum.getTypeQuestionChoiceNum()>0){
                            List<Question> questionList1=questionMapper.selectRandQuestionByTypeAndKnowledge(autoPaperQuestionNum.getKnowledgeName(),questionTypeNum.getQuestionType(),questionTypeNum.getTypeQuestionChoiceNum(),autoPaperQuestionNum.getDifficulty());
                            for(Question question:questionList1){
                                for (int i=0;i<questionTypeArr.length;i++){
                                    if(questionTypeArr[i].equals(questionTypeNum.getQuestionType())){
                                        typeScoreArr[i]=typeScoreArr[i]+questionTypeNum.getTypeScore();
                                    }
                                }
                                question.setContent(question.getContent()+"("+questionTypeNum.getTypeScore()+"分)");
                                question.setScore(questionTypeNum.getTypeScore());
                            }
                            if(questionList1!=null&&questionList1.size()>0){
                                questionList.addAll(questionList1);
                            }
                            isChoiceByType=true;
                        }
                    }
                }
                if(!isChoiceByType){
                    List<Question> questionList1=questionMapper.selectRandQuestionByKnowledge(autoPaperQuestionNum.getKnowledgeName(),autoPaperQuestionNum.getQuestionChoiceNum());
                    for(Question question:questionList1){
                        for (int i=0;i<questionTypeArr.length;i++){
                            if(questionTypeArr[i].equals(question.getQuestionType())){
                                typeScoreArr[i]=typeScoreArr[i]+autoPaperQuestionNum.getChoiceScore();
                            }
                        }
                        question.setContent(question.getContent()+"("+autoPaperQuestionNum.getChoiceScore()+"分)");
                        question.setScore(autoPaperQuestionNum.getChoiceScore());
                    }
                    if(questionList1!=null&&questionList1.size()>0){
                        questionList.addAll(questionList1);
                    }
                }
            }
        }
        index=1;
        questionIndex=1;

        Map<String,List<Question>> map=questionList.stream().filter(o -> Objects.nonNull(o.getQuestionType())).collect(Collectors.groupingBy(Question::getQuestionType));
        List<Map<String,Object>> allQuestionList=new ArrayList<>();
        for(Map.Entry<String,List<Question>> entry:map.entrySet()){
            for(int i=0;i<questionTypeArr.length;i++){
                if(entry.getKey().equals(questionTypeArr[i])){
                    allQuestionList.add(getQuestionList(entry.getValue(),entry.getKey(),paper.getId(),typeScoreArr[i],date));
                }
            }
        }
        dataMap.put("allQuestionList",allQuestionList);
        dataMap.put("paperName",exportFormValue.getPaperName());
        dataMap.put("answerTitle",exportFormValue.getPaperName()+"答案及评分标准");
        return dataMap;
    }

    private void insertPaperQuestion(Integer paperId, Integer questionNum, Integer score, String questionType, String questionIds, Date date){
        PaperQuestion paperQuestion=new PaperQuestion();
        paperQuestion.setIsDeleted(0);
        paperQuestion.setPaperId(paperId);
        paperQuestion.setQuestionNum(questionNum);
        paperQuestion.setQuestionType(questionType);
        paperQuestion.setScore(score);
        paperQuestion.setQuestionIds(questionIds);
        paperQuestion.setGmtCreate(date);
        paperQuestion.setGmtModified(date);
        paperQuestionMapper.insert(paperQuestion);
    }
    private Map<String,Object> getQuestionList(Integer paperid,Integer num, Integer score,String questionType,Date date) {
        List<Question> questionList=questionMapper.selectDanRand(questionType,num);
        Map<String,Object> questionMap=new HashMap<>();
        questionMap.put("questionList", listToMap(questionList));
        questionMap.put("questionTitle",intToChinese(index)+"、"+questionType);
        index++;
        questionMap.put("score",score);
        questionMap.put("typeTotalScore",num*score);

        List<Integer> ids=questionList.stream().map(o -> {
            Question question = (Question) o;
            return question.getId();
        }).collect(Collectors.toList());
        insertPaperQuestion(paperid,num,score,questionType,ids.toString(),date);
        return questionMap;
    }
    private Map<String,Object> getQuestionList(List<Question> questionList,String questionType,Integer paperid,Integer typeTotalScore,Date date) {
        Map<String,Object> questionMap=new HashMap<>();
        questionMap.put("questionList", listToMap(questionList));
        questionMap.put("questionTitle", intToChinese(index)+"、"+questionType);
        index++;
        questionMap.put("typeTotalScore",typeTotalScore);
        List<Integer> ids=questionList.stream().map(o -> {
            Question question = (Question) o;
            return question.getId();
        }).collect(Collectors.toList());
        insertPaperQuestion(paperid,questionList.size(),typeTotalScore,questionType,ids.toString(),date);
        return questionMap;
    }

    private static final String[] NUMS = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
    public static String intToChinese(Integer index){
        return NUMS[index];
    }

    /**
     * List<Question>转为List<Map<String,Object>>
     * @param questions
     * @return
     */
    private static List<Map<String,Object>> listToMap(List<Question> questions){
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(Question question:questions){
            Map<String,Object> map=new HashMap<>();
            map.put("content",questionIndex+". "+replaceSpecialCharacter(question.getContent()));
//            map.put("picture",question.getPicture());
            map.put("answer",questionIndex+". "+replaceSpecialCharacter(question.getAnswer()));
            map.put("questionType",question.getQuestionType());
            if(question.getQuestionType().equals("单选题")||question.getQuestionType().equals("多选题")){
                map.put("choiceA",replaceSpecialCharacter(question.getChoiceA()));
                map.put("choiceB",replaceSpecialCharacter(question.getChoiceB()));
                map.put("choiceC",replaceSpecialCharacter(question.getChoiceC()));
                map.put("choiceD",replaceSpecialCharacter(question.getChoiceD()));
                map.put("choiceE",replaceSpecialCharacter(question.getChoiceE()));
                map.put("choiceF",replaceSpecialCharacter(question.getChoiceF()));
                map.put("choiceG",replaceSpecialCharacter(question.getChoiceG()));
                map.put("choiceH",replaceSpecialCharacter(question.getChoiceH()));
            }
            mapList.add(map);
            questionIndex++;
        }
        return mapList;
    }

    /**
     * XML中的特殊字符替换成转义字符.
     */
    public static String replaceSpecialCharacter(String value) {
        if (value == null) {
            return null;
        }

        value = value.replaceAll("&", "&amp;");
        value = value.replaceAll("<", "&lt;");
        value = value.replaceAll(">", "&gt;");
        value = value.replaceAll("'", "&apos;");
        value = value.replaceAll("\"", "&quot;");
        value = value.replaceAll("\n", "<w:br />");
        return value;
    }
}
